﻿using DBCook.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Newtonsoft.Json;
using DBCook.Utils;
using DBCook.Common;
using DBUtil.Provider.SqlServer;
using DBUtil.Provider.SqlServer.MetaData;
using DBUtil.MetaData;
using Microsoft.AspNetCore.Hosting;
using System.IO;
using DBUtil;
using DotNetCommon.Data;
using DBUtil.Provider.MySql.MetaData;
using DBUtil.Provider.MySql;
using DotNetCommon.Extensions;

namespace DBCook.Services
{
    public class MySqlManageService
    {
        private readonly ILogger<MySqlManageService> logger;
        private readonly ISession session;
        private readonly IWebHostEnvironment webHostEnvironment;

        public MySqlManageService(ILogger<MySqlManageService> logger, ISession session, IWebHostEnvironment webHostEnvironment)
        {
            this.logger = logger;
            this.session = session;
            this.webHostEnvironment = webHostEnvironment;
        }

        public Result<bool> EntryDb(DbInfo dbInfo)
        {
            session.Set(Consts.CURRENT_DB, dbInfo);
            return Result.Ok(true);
        }

        public Result<List<MySqlTable>> GetAllTables(string table)
        {
            var db = session.GetDb() as MySqlAccess;
            var tables = db.Manage.ShowTables(null).Select(table => table as MySqlTable).ToList();
            if (!string.IsNullOrWhiteSpace(table))
            {
                tables = tables.Where(t => t.Name.IndexOf(table, StringComparison.OrdinalIgnoreCase) >= 0).ToList();
            }
            tables = tables.OrderBy(tbl => tbl.SchemaName + "." + tbl.Name).ToList();
            return Result.Ok(tables);
        }

        public Result<List<MySqlProcedure>> GetAllProcs(string schema, string proc)
        {
            var db = session.GetDb() as MySqlAccess;
            var tables = db.Manage.ShowProcedures().Select(proc => proc as MySqlProcedure).ToList();
            if (!string.IsNullOrWhiteSpace(schema))
            {
                tables = tables.Where(t => t.SchemaName.IndexOf(schema, StringComparison.OrdinalIgnoreCase) >= 0).ToList();
            }
            if (!string.IsNullOrWhiteSpace(proc))
            {
                tables = tables.Where(t => t.Name.IndexOf(proc, StringComparison.OrdinalIgnoreCase) >= 0).ToList();
            }
            tables = tables.OrderBy(tbl => tbl.SchemaName + "." + tbl.Name).ToList();
            return Result.Ok(tables);
        }

        public Result<List<MySqlFunction>> GetAllFuncs(string schema, string func)
        {
            var db = session.GetDb() as MySqlAccess;
            var tables = db.Manage.ShowFunctions().Select(proc => proc as MySqlFunction).ToList();
            if (!string.IsNullOrWhiteSpace(schema))
            {
                tables = tables.Where(t => t.SchemaName.IndexOf(schema, StringComparison.OrdinalIgnoreCase) >= 0).ToList();
            }
            if (!string.IsNullOrWhiteSpace(func))
            {
                tables = tables.Where(t => t.Name.IndexOf(func, StringComparison.OrdinalIgnoreCase) >= 0).ToList();
            }
            tables = tables.OrderBy(tbl => tbl.SchemaName + "." + tbl.Name).ToList();
            return Result.Ok(tables);
        }

        public Result<List<SqlServerSequence>> GetAllSeqs(string schema, string seq)
        {
            var db = session.GetDb() as SqlServerAccess;
            var tables = db.Manage.ShowSequences().Select(proc => proc as SqlServerSequence).ToList();
            if (!string.IsNullOrWhiteSpace(schema))
            {
                tables = tables.Where(t => t.SchemaName.IndexOf(schema, StringComparison.OrdinalIgnoreCase) >= 0).ToList();
            }
            if (!string.IsNullOrWhiteSpace(seq))
            {
                tables = tables.Where(t => t.Name.IndexOf(seq, StringComparison.OrdinalIgnoreCase) >= 0).ToList();
            }
            tables = tables.OrderBy(tbl => tbl.SchemaName + "." + tbl.Name).ToList();
            return Result.Ok(tables);
        }

        public Result<List<MySqlView>> GetAllViews(string schema, string view)
        {
            var db = session.GetDb() as MySqlAccess;
            var views = db.Manage.ShowViews().Select(view => view as MySqlView).ToList();
            if (!string.IsNullOrWhiteSpace(schema))
            {
                views = views.Where(t => t.SchemaName.IndexOf(schema, StringComparison.OrdinalIgnoreCase) >= 0).ToList();
            }
            if (!string.IsNullOrWhiteSpace(view))
            {
                views = views.Where(t => t.Name.IndexOf(view, StringComparison.OrdinalIgnoreCase) >= 0).ToList();
            }
            views = views.OrderBy(view => view.SchemaName + "." + view.Name).ToList();
            return Result.Ok(views);
        }

        public Result<MySqlTable> GetTableDetail(string table)
        {
            var db = session.GetDb();
            var tableDetail = (MySqlTable)db.Manage.ShowTableDetail(table);
            return Result.Ok(tableDetail);
        }

        public Result<MySqlView> GetViewDetail(string schema, string view)
        {
            var db = session.GetDb();
            var viewDetail = (MySqlView)db.Manage.ShowViewDetail(view, schema);
            return Result.Ok(viewDetail);
        }

        public ResultPage<Dictionary<string, object>> GetTableData(string table, string primaryKey, int pageIndex, int pageSize, string filter)
        {
            var db = session.GetDb();
            if (filter.IsNotNullOrEmptyOrWhiteSpace())
            {
                var tmp = filter.Trim().ToUpper();
                if (tmp.StartsWith("AND ") || tmp.StartsWith("OR "))
                {
                    filter = $" where 1=1 {filter}";
                }
                else
                {
                    filter = $" where {filter}";
                }
            }
            var sql = $"select * from `{table}` {filter}";
            var total = db.SelectScalar<int>($"select count(1) from `{table}` {filter}");
            var order = "";
            if (primaryKey.Contains(","))
            {
                order = "order by ";
                primaryKey.Split(',').ToList().ForEach(key =>
                {
                    order += $"`{key}`,";
                });
                order = order.TrimEnd(',');
            }
            else
            {
                order = $"order by `{primaryKey}`";
            }
            sql = db.GetSqlForPageSize(sql, order, pageSize, pageIndex);
            var dics = db.SelectDictionaryList(sql);
            return Result.OkPage(total, dics.ToArray());
        }

        public ResultPage<Dictionary<string, object>> GetViewData(string schema, string view, string primaryKey, int pageIndex, int pageSize)
        {
            var db = session.GetDb();
            var sql = $"select * from [{schema}].[{view}]";
            var total = db.SelectScalar<int>($"select count(1) from [{schema}].[{view}]");
            var order = "";
            if (primaryKey.Contains(","))
            {
                order = "order by ";
                primaryKey.Split(',').ToList().ForEach(key =>
                {
                    order += $"[{key}],";
                });
                order = order.TrimEnd(',');
            }
            else
            {
                order = $"order by [{primaryKey}]";
            }
            sql = db.GetSqlForPageSize(sql, order, pageSize, pageIndex);
            var dics = db.SelectDictionaryList(sql);
            return Result.OkPage(total, dics.ToArray());
        }

        public Result<string> AddConnect(DbInfo dbInfo)
        {
            if (string.IsNullOrWhiteSpace(dbInfo.Guid))
            {
                dbInfo.Guid = Guid.NewGuid().ToString().Replace("-", "").ToLower();
            }
            var path = Path.Combine(webHostEnvironment.WebRootPath, "config", "connections.json");
            var json = File.ReadAllText(path);
            var connections = Newtonsoft.Json.JsonConvert.DeserializeObject<List<DbInfo>>(json);
            connections.Add(dbInfo);
            json = Newtonsoft.Json.JsonConvert.SerializeObject(connections, Formatting.Indented);
            lock (typeof(ManageService))
            {
                File.WriteAllText(path, json);
            }
            return Result.Ok("保存成功!");
        }

        public Result<string> DeleteConnect(string guid)
        {
            var path = Path.Combine(webHostEnvironment.WebRootPath, "config", "connections.json");
            var json = File.ReadAllText(path);
            var connections = Newtonsoft.Json.JsonConvert.DeserializeObject<List<DbInfo>>(json);
            var conn = connections.FirstOrDefault(db => db.Guid == guid);
            connections.Remove(conn);
            json = Newtonsoft.Json.JsonConvert.SerializeObject(connections, Formatting.Indented);
            lock (typeof(ManageService))
            {
                File.WriteAllText(path, json);
            }
            return Result.Ok("删除成功!");
        }

        public Result<string> TestConnect(DbInfo dbInfo)
        {
            Result res = null;
            DBAccess db = null;
            if (dbInfo.Type == "MySql")
            {
                db = DBFactory.CreateDB(dbInfo.Type, $"Data Source={dbInfo.Addr};Initial Catalog={dbInfo.Db};User ID={dbInfo.User};Password={dbInfo.Pwd};");
            }
            else if (dbInfo.Type == "SqlServer")
            {
                db = DBFactory.CreateDB(dbInfo.Type, $"Data Source={dbInfo.Addr};Initial Catalog={dbInfo.Db};User={dbInfo.User};Password={dbInfo.Pwd};");
            }

            res = db.OpenTest();
            if (res.Success) return Result.Ok(res.Message);
            else return Result.NotOk(res.Message);
        }

        public Result<string> GetCreateTableSql(string table)
        {
            var db = session.GetDb();
            return Result.Ok(db.Manage.GenerateCreateTableSql(table));
        }

        public Result<string> GetCreateProcSql(string schema, string proc)
        {
            var db = session.GetDb();
            return Result.Ok(((MySqlManage)db.Manage).GenerateCreateProcSql(proc, null));
        }

        public Result<string> GetCreateFuncSql(string schema, string proc)
        {
            var db = session.GetDb();
            return Result.Ok(((SqlServerManage)db.Manage).GenerateCreateFuncSql(schema, proc));
        }

        public Result<string> GetCreateViewSql(string schema, string view)
        {
            var db = session.GetDb();
            return Result.Ok(((SqlServerManage)db.Manage).GenerateCreateViewSql(schema, view));
        }

        public Result<string> GetCreateSeqSql(string schema, string seq)
        {
            var db = session.GetDb();
            return Result.Ok(((SqlServerManage)db.Manage).GenerateCreateSeqSql(schema, seq));
        }

        public Result<(long count, string sql, long total)> GetInsertTableSql(string table, int count, string filter)
        {
            var db = session.GetDb();
            return Result.Ok(db.Manage.GenerateInsertSql(null, table, count, filter));
        }

        public Result<(long count, string sql, long total)> GetInsertViewSql(string schema, string view, int count)
        {
            var db = session.GetDb();
            return Result.Ok(((SqlServerManage)db.Manage).GenerateInsertViewSql(schema, view, count));
        }

        public string CreateInsertFile(string schema, string table, string filter)
        {
            var db = session.GetDb();
            var dir = Path.Combine(webHostEnvironment.ContentRootPath, "export-sqls");
            var abspath = Path.Combine(dir, $"{schema}-{table}-{DateTime.Now.ToString("yyyyMMddHHmmss")}");
            var count = db.Manage.GenerateInsertSqlFile(schema, table, abspath, 0, filter);
            return abspath;
        }

        public string CreateInsertViewFile(string schema, string view)
        {
            var db = session.GetDb();
            var dir = Path.Combine(webHostEnvironment.ContentRootPath, "export-sqls");
            var abspath = Path.Combine(dir, $"{schema}-{view}-{DateTime.Now.ToString("yyyyMMddHHmmss")}");
            var count = ((SqlServerManage)db.Manage).GenerateInsertViewSqlFile(schema, view, abspath);
            return abspath;
        }

        public Result<string> GetTableCode(string table)
        {
            var db = session.GetDb();
            var dir = Path.Combine(webHostEnvironment.ContentRootPath, "export-codes");
            var abspath = Path.Combine(dir, $"{table}-{DateTime.Now.ToString("yyyyMMddHHmmss")}");
            var code = db.Manage.GenerateCode(table, null);
            return Result.Ok(code);
        }

        public Result<string> GetViewCode(string schema, string view)
        {
            var db = session.GetDb();
            var dir = Path.Combine(webHostEnvironment.ContentRootPath, "export-codes");
            var abspath = Path.Combine(dir, $"{schema}-{view}-{DateTime.Now.ToString("yyyyMMddHHmmss")}");
            var code = ((SqlServerManage)db.Manage).GenerateViewCode(schema, view);
            return Result.Ok(code);
        }

        public Result<string> GetCreateTableSqlBatch(List<Table> tables, bool includeInsert = false)
        {
            var db = session.GetDb();
            var dir = Path.Combine(webHostEnvironment.ContentRootPath, "export-sqls");
            var name = $"{db.DataBase}-batch-Table-{DateTime.Now.ToString("yyyyMMddHHmmss")}.sql";
            var abspath = Path.Combine(dir, name);
            db.Manage.GenerateCreateTableSqlFile(tables, abspath, includeInsert);
            return Result.Ok(name);
        }

        public Result<string> GetCreateViewSqlBatch(List<View> views)
        {
            var db = session.GetDb();
            var dir = Path.Combine(webHostEnvironment.ContentRootPath, "export-sqls");
            var name = $"{db.DataBase}-batch-View-{DateTime.Now.ToString("yyyyMMddHHmmss")}.sql";
            var abspath = Path.Combine(dir, name);
            ((SqlServerManage)db.Manage).GenerateCreateViewSqlFile(views, abspath);
            return Result.Ok(name);
        }

        public Result<string> GetCreateFuncSqlBatch(List<Function> funcs)
        {
            var db = session.GetDb();
            var dir = Path.Combine(webHostEnvironment.ContentRootPath, "export-sqls");
            var name = $"{db.DataBase}-batch-Func-{DateTime.Now.ToString("yyyyMMddHHmmss")}.sql";
            var abspath = Path.Combine(dir, name);
            ((SqlServerManage)db.Manage).GenerateCreateFuncSqlFile(funcs, abspath);
            return Result.Ok(name);
        }

        public Result<string> GetCreateProcSqlBatch(List<Procedure> procs)
        {
            var db = session.GetDb();
            var dir = Path.Combine(webHostEnvironment.ContentRootPath, "export-sqls");
            var name = $"{db.DataBase}-batch-Proc-{DateTime.Now.ToString("yyyyMMddHHmmss")}.sql";
            var abspath = Path.Combine(dir, name);
            ((SqlServerManage)db.Manage).GenerateCreateProcSqlFile(procs, abspath);
            return Result.Ok(name);
        }

        public Result<string> GetCreateSeqSqlBatch(List<Sequence> seqs)
        {
            var db = session.GetDb();
            var dir = Path.Combine(webHostEnvironment.ContentRootPath, "export-sqls");
            var name = $"{db.DataBase}-batch-Seq-{DateTime.Now.ToString("yyyyMMddHHmmss")}.sql";
            var abspath = Path.Combine(dir, name);
            ((SqlServerManage)db.Manage).GenerateCreateSeqSqlFile(seqs, abspath);
            return Result.Ok(name);
        }

        /// <summary>
        /// 更新表说明
        /// </summary>
        /// <param name="name"></param>
        /// <param name="desc"></param>
        /// <returns></returns>
        public Result<string> UpdateTableDescription(string name, string desc)
        {
            var db = session.GetDb();
            var res = (db.Manage as MySqlManage).UpdateTableDescription(name, desc);
            return new Result<string>()
            {
                Success = res.Success,
                Message = res.Message
            };
        }

        /// <summary>
        /// 更新视图说明
        /// </summary>
        /// <param name="name"></param>
        /// <param name="schemaName"></param>
        /// <param name="desc"></param>
        /// <returns></returns>
        public Result<string> UpdateViewDescription(string name, string schemaName, string desc)
        {
            var db = session.GetDb();
            var res = (db.Manage as SqlServerManage).UpdateViewDescription($"[{schemaName}].[{name}]", desc);
            return new Result<string>()
            {
                Success = res.Success,
                Message = res.Message
            };
        }

        /// <summary>
        /// 更新函数说明
        /// </summary>
        /// <param name="name"></param>
        /// <param name="schemaName"></param>
        /// <param name="desc"></param>
        /// <returns></returns>
        public Result<string> UpdateFuncDescription(string name, string schemaName, string desc)
        {
            var db = session.GetDb();
            var res = (db.Manage as SqlServerManage).UpdateFuncDescription($"[{schemaName}].[{name}]", desc);
            return new Result<string>()
            {
                Success = res.Success,
                Message = res.Message
            };
        }

        /// <summary>
        /// 更新存储过程说明
        /// </summary>
        /// <param name="name"></param>
        /// <param name="schemaName"></param>
        /// <param name="desc"></param>
        /// <returns></returns>
        public Result<string> UpdateProcDescription(string name, string schemaName, string desc)
        {
            var db = session.GetDb();
            var res = (db.Manage as SqlServerManage).UpdateProcDescription($"[{schemaName}].[{name}]", desc);
            return new Result<string>()
            {
                Success = res.Success,
                Message = res.Message
            };
        }


        public Result<string> UpdateColumnDescription(string name, string tableName, string desc)
        {
            var db = session.GetDb();
            var res = db.Manage.UpdateColumnDescription(tableName, name, desc);
            return new Result<string>()
            {
                Success = res.Success,
                Message = res.Message
            };
        }

        public Result<string> UpdateColumnNullAble(string name, string tableName, string isNullAble)
        {
            var db = session.GetDb();
            var res = db.Manage.UpdateColumnNullAble(tableName, name, isNullAble.To<bool>(), null);
            return new Result<string>()
            {
                Success = res.Success,
                Message = res.Message
            };
        }

        public Result<string> UpdateColumnUnique(string name, string tableName, string isUnique)
        {
            var db = session.GetDb();
            var res = db.Manage.UpdateColumnUnique(tableName, name, isUnique.To<bool>(), null);
            return new Result<string>()
            {
                Success = res.Success,
                Message = res.Message
            };
        }

        public Result<string> UpdateColumnIdentity(string name, string tableName, string identity)
        {
            var db = session.GetDb();
            var isIdentity = identity.To<bool>();
            var res = db.Manage.UpdateColumnIdentity(tableName, name, isIdentity ? "AUTO_INCREMENT" : "", null);
            return new Result<string>()
            {
                Success = res.Success,
                Message = res.Message
            };
        }

        public Result<string> UpdateColumnType(string name, string tableName, string typeString)
        {
            var db = session.GetDb();
            var res = db.Manage.UpdateColumnType(tableName, name, typeString);
            return new Result<string>()
            {
                Success = res.Success,
                Message = res.Message
            };
        }

        public Result<string> UpdateColumnName(string oldName, string newName, string tableName)
        {
            var db = session.GetDb();
            var res = db.Manage.RenameColumn(tableName, oldName, newName);
            return new Result<string>()
            {
                Success = res.Success,
                Message = res.Message
            };
        }

        public Result<string> UpdateViewColumnDescription(string name, string schemaName, string viewName, string desc)
        {
            var db = session.GetDb();
            var res = (db.Manage as SqlServerManage).UpdateViewColumnDescription($"[{schemaName}].[{viewName}]", name, desc);
            return new Result<string>()
            {
                Success = res.Success,
                Message = res.Message
            };
        }

        /// <summary>
        /// 对比两个数据库
        /// </summary>
        /// <param name="guid1">基础数据库</param>
        /// <param name="guid2">进行对比的数据库</param>
        /// <returns></returns>
        public Result CompareDB(string guid1, string guid2)
        {
            if (guid1.IsNullOrEmptyOrWhiteSpace() || guid2.IsNullOrEmptyOrWhiteSpace()) return Result.NotOk("参数错误!");
            var db1 = session.GetDb(guid1);
            var db2 = session.GetDb(guid2);

            var tmp1 = db1.Manage.ShowTables(null, true);
            var tmp2 = db2.Manage.ShowTables(null, true);

            var tables1 = tmp1.Select(i => i as MySqlTable).ToList();
            var tables2 = tmp2.Select(i => i as MySqlTable).ToList();

            var result = new CompareDBResult()
            {
                Tables = new List<CompareDBResult.TableResult>()
            };

            var tableResults = result.Tables;
            for (int i = 0; i < tables1.Count; i++)
            {
                var table1 = tables1[i];
                var table2 = tables2.FirstOrDefault(j => j.Name == table1.Name);
                if (table2 == null)
                {
                    //删除了表
                    tableResults.Add(new CompareDBResult.TableResult
                    {
                        Type = CompareDBResult.EnumResultType.Delete,
                        Name = table1.Name
                    });
                }
                else
                {
                    //更新
                    var tableResult = new CompareDBResult.TableResult()
                    {
                        Name = table1.Name,
                        Type = CompareDBResult.EnumResultType.Update,
                        Columns = new List<CompareDBResult.ColumnResult>(),
                        Indexes = new List<CompareDBResult.IndexResult>()
                    };

                    #region 列
                    var columnResults = tableResult.Columns;

                    var columns1 = table1.Columns;
                    var columns2 = table2.Columns;
                    for (int p = 0; p < columns1.Count; p++)
                    {
                        var column1 = columns1[p];
                        var column2 = columns2.FirstOrDefault(j => j.Name == column1.Name);
                        if (column2 == null)
                        {
                            //删除了列
                            columnResults.Add(new CompareDBResult.ColumnResult
                            {
                                Type = CompareDBResult.EnumResultType.Delete,
                                Name = column1.Name
                            });
                        }
                        else
                        {
                            //更新列
                            var columnResult = new CompareDBResult.ColumnResult()
                            {
                                Type = CompareDBResult.EnumResultType.Update,
                                Name = column1.Name,
                                Parameters = new List<CompareDBResult.ParameterResult>()
                            };
                            var parameters = columnResult.Parameters;
                            //列类型
                            if (column1.TypeString != column2.TypeString)
                            {
                                if ((column1.TypeString == "int" && column2.TypeString == "int(11)") || (column1.TypeString == "int(11)" && column2.TypeString == "int"))
                                { }
                                else if ((column1.TypeString == "bigint" && column2.TypeString == "bigint(20)") || (column1.TypeString == "bigint(20)" && column2.TypeString == "bigint"))
                                { }
                                else if ((column1.TypeString == "smallint" && column2.TypeString == "smallint(6)") || (column1.TypeString == "smallint(6)" && column2.TypeString == "smallint"))
                                { }
                                else
                                {
                                    parameters.Add(new CompareDBResult.ParameterResult
                                    {
                                        Name = "TypeString",
                                        Type = CompareDBResult.EnumResultType.Update,
                                        Value1 = column1.TypeString,
                                        Value2 = column2.TypeString,
                                    });
                                }
                            }
                            //是否可空
                            if (column1.IsNullAble != column2.IsNullAble)
                            {
                                parameters.Add(new CompareDBResult.ParameterResult
                                {
                                    Name = "IsNullAble",
                                    Type = CompareDBResult.EnumResultType.Update,
                                    Value1 = column1.IsNullAble,
                                    Value2 = column2.IsNullAble,
                                });
                            }
                            //是否可空
                            if (column1.Default != column2.Default)
                            {
                                parameters.Add(new CompareDBResult.ParameterResult
                                {
                                    Name = "Default",
                                    Type = CompareDBResult.EnumResultType.Update,
                                    Value1 = column1.Default,
                                    Value2 = column2.Default,
                                });
                            }
                            //是否唯一
                            if (column1.IsUnique != column2.IsUnique)
                            {
                                parameters.Add(new CompareDBResult.ParameterResult
                                {
                                    Name = "IsUnique",
                                    Type = CompareDBResult.EnumResultType.Update,
                                    Value1 = column1.IsUnique,
                                    Value2 = column2.IsUnique,
                                });
                            }
                            //是否是主键
                            if (column1.IsPrimaryKey != column2.IsPrimaryKey)
                            {
                                parameters.Add(new CompareDBResult.ParameterResult
                                {
                                    Name = "IsPrimaryKey",
                                    Type = CompareDBResult.EnumResultType.Update,
                                    Value1 = column1.IsPrimaryKey,
                                    Value2 = column2.IsPrimaryKey,
                                });
                            }
                            if (parameters.IsNotNullOrEmpty()) columnResults.Add(columnResult);
                        }
                    }
                    for (int p = 0; p < columns2.Count; p++)
                    {
                        var column2 = columns2[p];
                        if (!columns1.Any(j => j.Name == column2.Name))
                        {
                            //增加了列
                            columnResults.Add(new CompareDBResult.ColumnResult
                            {
                                Type = CompareDBResult.EnumResultType.Add,
                                Name = column2.Name
                            });
                        }
                    }
                    #endregion

                    #region 索引
                    var indexResults = tableResult.Indexes;

                    var indexes1 = table1.Indexes;
                    var indexes2 = table2.Indexes;

                    //先根据名字找对应
                    for (int p = 0; p < indexes1.Count; p++)
                    {
                        var index1 = indexes1[p];
                        var index2 = indexes2.FirstOrDefault(j => j.Name == index1.Name);
                        if (index2 == null) index2 = indexes2.FirstOrDefault(j => j.ColumnNames == index1.ColumnNames);
                        if (index2 == null)
                        {
                            //删除了索引
                            indexResults.Add(new CompareDBResult.IndexResult
                            {
                                Type = CompareDBResult.EnumResultType.Delete,
                                ColumnNames = index1.ColumnNames,
                                Description = $"索引: {index1.Name},列: {index1.ColumnNames}"
                            });
                        }
                        else
                        {
                            indexes2.Remove(index2);
                            //更新了索引
                            var indexResult = new CompareDBResult.IndexResult()
                            {
                                Type = CompareDBResult.EnumResultType.Update,
                                Description = $"索引: {index1.Name},列: {index1.ColumnNames}",
                                Parameters = new List<CompareDBResult.ParameterResult>()
                            };
                            var parameters = indexResult.Parameters;
                            //索引名
                            if (index1.Name != index2.Name)
                            {
                                parameters.Add(new CompareDBResult.ParameterResult
                                {
                                    Name = "索引名字",
                                    Type = CompareDBResult.EnumResultType.Update,
                                    Value1 = index1.Name,
                                    Value2 = index2.Name,
                                });
                            }
                            //索引列
                            if (index1.ColumnNames != index2.ColumnNames)
                            {
                                parameters.Add(new CompareDBResult.ParameterResult
                                {
                                    Name = "列名字",
                                    Type = CompareDBResult.EnumResultType.Update,
                                    Value1 = index1.ColumnNames,
                                    Value2 = index2.ColumnNames,
                                });
                            }
                            //索引类型
                            if (index1.IndexType != index2.IndexType)
                            {
                                parameters.Add(new CompareDBResult.ParameterResult
                                {
                                    Name = "索引类型",
                                    Type = CompareDBResult.EnumResultType.Update,
                                    Value1 = index1.IndexType,
                                    Value2 = index2.IndexType,
                                });
                            }
                            //索引可为空
                            if (index1.IsNullAble != index2.IsNullAble)
                            {
                                parameters.Add(new CompareDBResult.ParameterResult
                                {
                                    Name = "索引可为空",
                                    Type = CompareDBResult.EnumResultType.Update,
                                    Value1 = index1.IsNullAble,
                                    Value2 = index2.IsNullAble,
                                });
                            }
                            //索引是否唯一
                            if (index1.IsUnique != index2.IsUnique)
                            {
                                parameters.Add(new CompareDBResult.ParameterResult
                                {
                                    Name = "索引是否唯一",
                                    Type = CompareDBResult.EnumResultType.Update,
                                    Value1 = index1.IsUnique,
                                    Value2 = index2.IsUnique,
                                });
                            }
                            if (parameters.IsNotNullOrEmpty()) indexResults.Add(indexResult);
                        }
                    }
                    for (int p = 0; p < indexes2.Count; p++)
                    {
                        var index2 = indexes2[p];
                        //增加了索引
                        indexResults.Add(new CompareDBResult.IndexResult
                        {
                            Type = CompareDBResult.EnumResultType.Add,
                            Description = $"索引: {index2.Name},列: {index2.ColumnNames}"
                        });
                    }
                    #endregion

                    if (tableResult.Columns.IsNotNullOrEmpty() || tableResult.Indexes.IsNotNullOrEmpty()) tableResults.Add(tableResult);
                }
            }
            for (int i = 0; i < tables2.Count; i++)
            {
                var table2 = tables2[i];
                if (!tables1.Any(j => j.Name == table2.Name))
                {
                    //增加了表
                    tableResults.Add(new CompareDBResult.TableResult
                    {
                        Type = CompareDBResult.EnumResultType.Add,
                        Name = table2.Name
                    });
                }
            }
            return Result.Ok().SetData(result);
        }
    }
}
